#ifndef FLASH_CONTROL_H
#define FLASH_CONTROL_H
//
// Created by g on 2024/6/23.
//

#include "flash_control.h"

uint8_t dect_fl[26];

uint8_t control_buf[FLASH_MAX_SIZE];
lim32_basic_config_t lim32_basic_config={{0x4C,0x49,0x4D,0x20},
    {0xFF,0xFE,0xEF,0xFF},
    {{".txt"},{".bcf"}},
    {0x00,END,0x00,0x00,0x00,0x00,0xFF,0xFE,0xEF,0xFF},
    {0xFF},
    False};

//void flash_clear_all()
//{
//    for(int i=0;i<FLASH_MAX_SIZE;i++) {
//        control_buf[i]=0xFF;
//    }
//}

//void flash_clear_piece(uint32_t piece_id)
//{
//    for(int i=0;i<256;i++) {
//        control_buf[piece_id*256+i]=0xFF;
//    }
//}

//void flash_write_page(uint8_t* puf,uint32_t addr,uint16_t datalen)
//{
//    for(int i=0;i<datalen;i++) {
//        control_buf[i+addr]=puf[i];
//    }
//}

//void flash_read(uint8_t* puf,uint32_t addr,uint16_t datalen)
//{
//    for(int i=0;i<datalen;i++) {
//        puf[i]=control_buf[addr+i];
//    }
//}

//void flash_print()
//{
//    printf("\n\n\n");
//    for(int i=0;i<FLASH_MAX_SIZE/256;i++) {
//        for(int j=0;j<256;j++) {
//            if(j==0) {
//                printf("%d: %.2X",i,control_buf[i*256+j]);
//            }
//            else if(j!=255) {
//                printf(" %.2X",control_buf[i*256+j]);
//            }
//            else {
//                printf(" %.2X\n",control_buf[i*256+j]);
//            }
//        }
//    }
//    printf("\n\n\n");
//}

//void msg_log(uint8_t* msg,uint8_t level)
//{
//    switch (level) {
//        case 0:
//            printf("[Msg:]");
//            break;
//        case 1:
//            printf("[Error:]");
//            break;
//        default:
//            break;
//    }
//    printf("%s\n",msg);
//}


void flash_init(uint32_t flash_size)
{
    uint8_t head_read[2][4];
    flash_read(head_read[0],0,4);
    flash_read(head_read[1],8,4);
    if(list_compare(head_read[0],lim32_basic_config.head_start,4)==False || list_compare(head_read[1],lim32_basic_config.end_cmd,4)==False) {
//        msg_log("lim32 init start",0);
        flash_clear_all();
        uint8_t temp[12];
        for(int i=0;i<4;i++) {
            temp[i]=lim32_basic_config.head_start[i];
        }
        for(int i=0;i<4;i++) {
            temp[i+4]=0x00;
        }
        for(int i=0;i<4;i++) {
            temp[i+8]=lim32_basic_config.end_cmd[i];
        }
        flash_write_page(temp,0,12);
        lim32_basic_config.lim32_init_if=True;
//        msg_log("lim32 init finish",0);
    }
    else {
//        msg_log("lim32 has benn init",0);
    }
}

Bool creat_file(uint8_t* file_name,uint8_t file_name_len,File_Type file_type)
{
    Bool empty_piece_if=False;
    uint8_t file[12]={0x00};
    uint8_t file_name_8[8]={0x00};
    uint8_t nums[4];
    uint32_t file_nums=0x00;
    uint32_t file_config_write_start_pos=0;
    uint32_t file_data_write_start_piece=0;
    uint8_t file_data_write_addr[4];
    uint8_t last_file[8];
    uint32_t last_file_addr=0x00,last_file_size=0x00;
    uint8_t file_write[20];
    uint32_t file_size=0;

    if(lim32_basic_config.lim32_init_if==False) {
        flash_init(FLASH_MAX_SIZE);
    }
    if(file_name_len>8) {
        file_name_len=8;
    }
    for(int i=0;i<file_name_len;i++) {
        file_name_8[i]=file_name[i];
        file[i]=file_name[i];
    }
    memcpy(&file[8],lim32_basic_config.file_type[file_type],sizeof(lim32_basic_config.file_type[file_type]));
    file_nums=get_nums();
    if(file_nums>(FLASH_PIECE_MIN_SIZE-12)/20-1) {
        return False;
    }
    if(in_dir_if(file,file_nums)) {
        return False;
    }
    file_config_write_start_pos=file_nums*20+12;
    for(int i=0;i<FLASH_MAX_SIZE/FLASH_PIECE_MIN_SIZE;i++) {
        uint8_t flag[1];
        flash_read(flag,pieceid_to_addr(i),1);
        if(flag[0]==0xFF) {
            file_data_write_start_piece=i;
            empty_piece_if=True;
            break;
        }
    }
    if(empty_piece_if==False) {
        return False;
    }
    memcpy(file_write,file_name_8,sizeof(file_name_8));
    memcpy(&file_write[8],lim32_basic_config.file_type[file_type],sizeof(lim32_basic_config.file_type[file_type]));
    u32_to_u8(file_data_write_start_piece,&file_write[12]);
    u32_to_u8(file_size,&file_write[16]);
    file_nums++;
    u32_to_u8(file_nums,nums);
    flash_write_page(file_write,file_config_write_start_pos,20);
    flash_write_page(lim32_basic_config.file_init,pieceid_to_addr(file_data_write_start_piece),6);
    flash_write_page(&lim32_basic_config.file_init[6],pieceid_to_addr(file_data_write_start_piece+1)-4,4);
    flash_write_page(nums,4,4);
    return True;
}

Bool del_file(uint8_t* file_name,uint8_t file_name_len,File_Type file_type)
{
    int file_id_get=-1;
    uint32_t file_nums=0x00;
    uint8_t file[12]={0x00};
    for(int i=0;i<file_name_len;i++) {
        file[i]=file_name[i];
    }
    for(int i=file_name_len;i<8;i++) {
        file[i]=0x00;
    }
    for(int i=0;i<4;i++) {
        file[8+i]=(lim32_basic_config.file_type[file_type])[i];
    }
    file_nums=get_nums();
    if(file_nums==0) {
        return False;
    }
    else {
        file_id_get=get_file_id(file,file_nums);
        if(file_id_get==-1) {
            return False;
        }
        else {
            uint8_t del_start=True;
            uint8_t use_next=False;
            uint32_t id_use=0;
            uint32_t next_piece=0;
            uint8_t next_piece_get[2]={0x00};
            uint8_t cmd[1]={0x00};
            uint8_t nums[4];
            while(del_start) {
                if(use_next==True) {
                    id_use=next_piece;
                }
                else {
                    id_use=file_id_get;
                }
                flash_read(cmd,pieceid_to_addr(id_use)+1,1);
                if(cmd[0]==END) {
                    del_start=False;
                    flash_clear_piece(1+id_use);
                }
                else if(cmd[0]==JUMP){
                    flash_read(next_piece_get,pieceid_to_addr(id_use)+2,2);
                    next_piece=next_piece_get[0]<<8 | next_piece_get[1];
                    flash_clear_piece(1+id_use);
                    use_next=True;
                }
                else {
                    return False;
                }
            }
            if(file_nums-file_id_get==0) {
                flash_write_page(lim32_basic_config.empty_file,12+20*file_id_get,20);
            }
            for(int i=file_id_get;i<file_nums;i++) {
                uint8_t next_file[20];
                flash_read(next_file,12+(i+1)*20,20);
                flash_write_page(next_file,12+20*i,20);
            }
            flash_write_page(lim32_basic_config.empty_file,12+(file_nums-1)*20,20);
            u32_to_u8(file_nums-1,nums);
            flash_write_page(nums,4,4);
            return True;
        }
    }
}

Bool open_file(File_operate_t* temp_f,uint8_t* file_name,uint8_t file_name_len,File_Type file_type,Con_type con_type)
{
    uint8_t start_piece[4];
    for(int i=0;i<file_name_len;i++) {
        temp_f->file[i]=file_name[i];
    }
    for(int i=file_name_len;i<8;i++){
        temp_f->file[i]=0x00;
    }
    memcpy(&temp_f->file[8],lim32_basic_config.file_type[file_type],sizeof(lim32_basic_config.file_type[file_type]));
    if(in_dir_if(temp_f->file,get_nums())==False) {
        temp_f->init_scusses_if=False;
        return False;
    }
    else {
        temp_f->file_id=get_file_id(temp_f->file,get_nums());
        temp_f->config_addr=temp_f->file_id*20+12;
        flash_read(start_piece,temp_f->config_addr+12,4);
        temp_f->start_piece=u8_to_u32(start_piece);
        temp_f->now_piece=temp_f->start_piece;
        temp_f->now_addr=pieceid_to_addr(temp_f->start_piece)+4;
        temp_f->rewrite_clear_if=False;
        temp_f->append_init_if=False;
        temp_f->init_scusses_if=True;
        temp_f->con_type=con_type;
        temp_f->now_offset=0;
        file_size_calu(temp_f);
        return True;
    }
}

Bool file_write(File_operate_t* temp_f,uint8_t* datas,uint32_t data_len)
{
    Bool ret=False;
    Bool new_piece_if=False,empty_piece_if=False;
    Bool memory_move_if=False;
    uint32_t surplus_len=data_len,this_time_write_len=0,new_piece=0,surplus_size=0;
    uint8_t size_get=0,new_size[1]={0x00};
    uint32_t offset_record=temp_f->now_offset;
    if(temp_f->init_scusses_if==False) {
        return False;
    }
    if(temp_f->con_type==Rewrite) {
        if(temp_f->rewrite_clear_if==False){
            file_clear(temp_f);
            temp_f->rewrite_clear_if=True;
        }
    }
    else if(temp_f->con_type==Append){
        if(temp_f->append_init_if==False){
            temp_f->now_offset=0;
            offset_move(temp_f,RIGHT,temp_f->now_size);
            temp_f->append_init_if=True;
        }
    }
    if(temp_f->now_offset<temp_f->now_size) {
        memory_move_if=True;
    }
    while(memory_move_if) {
        uint32_t datalen_to_move=temp_f->now_size-temp_f->now_offset;
        file_data_move(temp_f,temp_f->now_offset,temp_f->now_offset+datalen_to_move,data_len,RIGHT);
        memory_move_if=False;
    }
    temp_f->now_offset=offset_record;
    file_write_data(temp_f,datas,temp_f->now_offset,data_len);
    temp_f->now_offset+=data_len;
    file_size_calu(temp_f);
    ret=True;
    file_size_calu(temp_f);
    return ret;
}

Bool file_delete_data(File_operate_t* temp_f,uint32_t del_offset_start,uint32_t del_distances)
{
    Bool ret=False;
    if(temp_f->init_scusses_if==False) {
        return False;
    }
    if(del_offset_start<del_distances) {
        del_distances=del_offset_start;
    }
    file_data_move(temp_f,del_offset_start,temp_f->now_size,del_distances,LEFT);
    file_size_del(temp_f,del_distances);
    ret=True;
    return ret;
}

Bool file_size_del(File_operate_t* temp_f,uint32_t del_offset)
{
    Bool ret=False;
    uint16_t now_piece=0;
    uint8_t cmd[1],next_piece_u8[2],new_size[1];
    if(temp_f->init_scusses_if==False) {
        return False;
    }
    if(del_offset>temp_f->now_size) {
        del_offset=temp_f->now_size;
    }
    Bool jump_if=False,del_start_if=False,rewrite_size_if=False;
    uint32_t size_surplus=temp_f->now_size-del_offset;
    uint32_t after_del_piece_full_use=(temp_f->now_size-del_offset)/FLASH_USEFUL_DATA_LEN;
    uint32_t after_del_piece_not_full_use=(temp_f->now_size-del_offset)%FLASH_USEFUL_DATA_LEN==0?0:1;
    if(after_del_piece_full_use+after_del_piece_not_full_use==0) {
        after_del_piece_not_full_use=1;
    }
    uint32_t now_total_piece=(temp_f->now_size)/FLASH_USEFUL_DATA_LEN+(temp_f->now_size)%FLASH_USEFUL_DATA_LEN==0?0:1;
    if(now_total_piece==0) {
        now_total_piece++;
    }
    uint32_t piece_surplus=now_total_piece-(after_del_piece_full_use+after_del_piece_not_full_use)+1;
    now_piece=temp_f->start_piece;
    if(piece_surplus==0 && del_offset!=0) {
        piece_surplus=1;
    }
    while(piece_surplus>0) {
        if(del_start_if==False) {
            if(size_surplus>=FLASH_USEFUL_DATA_LEN) {
                jump_if=True;
                size_surplus-=FLASH_USEFUL_DATA_LEN;
            }
            else if(size_surplus<FLASH_USEFUL_DATA_LEN) {
                rewrite_size_if=True;
                new_size[0]=size_surplus;
                size_surplus=0;
            }
        }
        if(jump_if==True) {
            flash_read(cmd,pieceid_to_addr(now_piece)+1,1);
            flash_read(next_piece_u8,pieceid_to_addr(now_piece)+2,2);
            if(cmd[0]==END) {
                del_start_if=False;
                piece_surplus--;
            }
            jump_if=False;
        }
        if(del_start_if==True) {
            flash_clear_piece(now_piece);
            piece_surplus--;
            jump_if=True;
        }
        if(rewrite_size_if==True) {
            flash_write_page(new_size,pieceid_to_addr(now_piece),1);
            rewrite_size_if=False;
            del_start_if=True;
            piece_surplus--;
        }
        now_piece=next_piece_u8[0]<<8 | next_piece_u8[1];
    }
    file_size_calu(temp_f);
    ret=True;
    return ret;
}

Bool file_data_move(File_operate_t* temp_f,uint32_t move_start_offset,uint32_t move_end_offset,uint32_t move_distance,OFFSET_DIRECTION dir)
{
    Bool ret=False;
    uint32_t memory_to_move;
    uint8_t full_piece_cut=0,some_piece_cut=1,full_piece_del=0;
    if(temp_f->init_scusses_if==False) {
        return False;
    }
    if(move_end_offset<move_start_offset) {
        uint32_t temp=move_end_offset;
        move_end_offset=move_start_offset;
        move_start_offset=temp;
    }
    if(move_end_offset>temp_f->now_size) {
        move_end_offset=temp_f->now_size;
    }
    if(move_start_offset>temp_f->now_size) {
        move_start_offset=temp_f->now_size;
    }
    memory_to_move=move_end_offset-move_start_offset;
    if(dir==RIGHT) {
        if(move_end_offset+move_distance>temp_f->now_size) {
            uint32_t memory_to_apply=move_end_offset+move_distance-temp_f->now_size;
            uint32_t apply_times=memory_to_apply/FLASH_USEFUL_DATA_LEN+1;
            for(int i=0;i<apply_times;i++) {
                file_write_data(temp_f,lim32_basic_config.none_data,temp_f->now_size,(i==apply_times-1)?(memory_to_apply-i*FLASH_USEFUL_DATA_LEN):FLASH_USEFUL_DATA_LEN);
            }

        }
    }
    else if(dir==LEFT) {
        if(move_start_offset<move_distance) {
            move_distance=move_start_offset;
        }
    }
    uint8_t move_temp[248]={0xFF};
    full_piece_cut=memory_to_move/FLASH_USEFUL_DATA_LEN;
    if(dir==RIGHT) {
        while(memory_to_move>0) {
            uint32_t this_time_read_offset=0;
            uint32_t this_time_read_len=0;
            uint32_t this_time_write_offset=0;
            uint32_t this_time_write_len=0;
            if(some_piece_cut>0) {
                this_time_read_offset=move_end_offset-memory_to_move%FLASH_USEFUL_DATA_LEN;
                this_time_read_len=memory_to_move%FLASH_USEFUL_DATA_LEN;
                this_time_write_len=this_time_read_len;
                this_time_write_offset=this_time_read_offset+move_distance;
                some_piece_cut--;
            }
            else if(full_piece_cut>0) {
                this_time_read_offset=move_end_offset-memory_to_move%FLASH_USEFUL_DATA_LEN-(full_piece_del+1)*FLASH_USEFUL_DATA_LEN;
                this_time_read_len=FLASH_USEFUL_DATA_LEN;
                this_time_write_len=this_time_read_len;
                this_time_write_offset=this_time_read_offset+move_distance;
                full_piece_cut--;
                some_piece_cut++;
            }
            memory_to_move-=this_time_read_len;
            file_read(temp_f,move_temp,this_time_read_offset,this_time_read_len);
            file_write_data(temp_f,move_temp,this_time_write_offset,this_time_write_len);
        }
    }
    else if(dir==LEFT) {
        while(memory_to_move>0) {
            uint32_t this_time_read_offset=0;
            uint32_t this_time_read_len=0;
            uint32_t this_time_write_offset=0;
            uint32_t this_time_write_len=0;
            if(some_piece_cut>0) {
                this_time_read_offset=move_start_offset;
                this_time_read_len=memory_to_move%FLASH_USEFUL_DATA_LEN;
                this_time_write_len=this_time_read_len;
                this_time_write_offset=this_time_read_offset-move_distance;
                some_piece_cut--;
            }
            else if(full_piece_cut>0) {
                this_time_read_offset=move_start_offset+memory_to_move%FLASH_USEFUL_DATA_LEN+(full_piece_del)*FLASH_USEFUL_DATA_LEN;
                this_time_read_len=FLASH_USEFUL_DATA_LEN;
                this_time_write_len=this_time_read_len;
                this_time_write_offset=this_time_read_offset-move_distance;
                full_piece_cut--;
                some_piece_cut++;
            }
            memory_to_move-=this_time_read_len;
            file_read(temp_f,move_temp,this_time_read_offset,this_time_read_len);
            file_write_data(temp_f,move_temp,this_time_write_offset,this_time_write_len);
        }
    }
    ret=True;
    return ret;
}

Bool file_clear(File_operate_t* temp_f)
{
    Bool ret=False;
    Bool clear_if=False;
    uint8_t now_piece_u8[2]={0x00};
    uint8_t cmd[1]={0x00};
    uint16_t now_piece=temp_f->start_piece;
    if(temp_f->init_scusses_if==False){
        return False;
    }
    else{
        while(clear_if==False){
            flash_read(cmd, pieceid_to_addr(now_piece)+1,1);
            flash_read(now_piece_u8, pieceid_to_addr(now_piece)+2,2);
            flash_clear_piece(now_piece);
            if(now_piece==temp_f->start_piece){
                flash_write_page(lim32_basic_config.file_init,pieceid_to_addr(now_piece),6);
                flash_write_page(&lim32_basic_config.file_init[6],pieceid_to_addr(now_piece+1)-4,4);
            }
            if(cmd[0]==END){
                temp_f->now_offset=0;
                temp_f->now_piece=temp_f->start_piece;
                temp_f->now_addr=pieceid_to_addr(temp_f->start_piece)+4;
                clear_if=True;
                ret=True;
            }
            else if(cmd[0]==JUMP){
                now_piece=now_piece_u8[0]<<8 | now_piece_u8[1];
            }
            else{
                return False;
            }
        }
    }
    file_size_calu(temp_f);
    return ret;
}

Bool file_close(File_operate_t* temp_f)
{
    temp_f->init_scusses_if=False;
    return True;
}

Bool file_size_calu(File_operate_t* temp_f)
{
    Bool ret=False;
    Bool end_if=False;
    uint8_t now_piece_u8[2]={0x00};
    uint8_t cmd[1]={0x00},new_size[4]={0x00};
    uint16_t now_piece=temp_f->start_piece;
    uint32_t total_size=0;
    if(temp_f->init_scusses_if==False){
        return False;
    }
    else{
        while (end_if==False){
            flash_read(cmd, pieceid_to_addr(now_piece)+1,1);
            flash_read(now_piece_u8, pieceid_to_addr(now_piece)+2,2);
            total_size+= get_piece_size(now_piece);
            if(cmd[0]==END){
                u32_to_u8(total_size,new_size);
                temp_f->now_size=total_size;
                flash_write_page(new_size,temp_f->config_addr+16,4);
                end_if=True;
                ret=True;
            }
            else if(cmd[0]==JUMP){
                now_piece=now_piece_u8[0]<<8 | now_piece_u8[1];
            }
            else{
                return False;
            }
        }
    }
    return ret;
}

Bool file_read_all(File_operate_t* temp_f)
{
    Bool ret=False;
    Bool end_if=False;
    uint8_t read_buf[FLASH_USEFUL_DATA_LEN];
    uint8_t now_piece_u8[2]={0x00},piece_size_u8[1]= {0x00};
    uint8_t cmd[1]={0x00};
    uint32_t print_size=0;
    uint16_t now_piece=temp_f->start_piece;
    if(temp_f->init_scusses_if==False){
        return False;
    }
    else{
        // printf("Read:\n");
        while (end_if==False){
            flash_read(piece_size_u8, pieceid_to_addr(now_piece),1);
            flash_read(cmd, pieceid_to_addr(now_piece)+1,1);
            flash_read(now_piece_u8, pieceid_to_addr(now_piece)+2,2);
            flash_read(read_buf, pieceid_to_addr(now_piece)+4,piece_size_u8[0]);
            if(cmd[0]==END){
                end_if=True;
                ret=True;
            }
            else if(cmd[0]==JUMP){
                now_piece=now_piece_u8[0]<<8 | now_piece_u8[1];
                print_size+=piece_size_u8[0];
            }
            else{
                return False;
            }
        }
    }
    return ret;
}

Bool file_read(File_operate_t* temp_f,uint8_t* puf,uint32_t read_offset_start,uint32_t offset)
{
    Bool ret=False;
    Bool end_if=False,jump_if=False;
    uint8_t next_piece_8[2];
    uint32_t total_read_byte=0,surplus_size;
    uint32_t this_time_read_len=0;
    if(temp_f->init_scusses_if==False) {
        return False;
    }
    if(read_offset_start>temp_f->now_size) {
        read_offset_start=temp_f->now_size;
    }
    if(read_offset_start+offset>temp_f->now_size) {
        offset=temp_f->now_size-read_offset_start;
    }
    surplus_size=offset;
    temp_f->now_offset=0;
    offset_move(temp_f,RIGHT,read_offset_start);
    while(surplus_size>0) {
        uint32_t this_piece_end_addr=pieceid_to_addr(temp_f->now_piece)+FLASH_USEFUL_DATA_LEN+4;
        uint32_t surplus_to_read=this_piece_end_addr-temp_f->now_addr;
        if(surplus_to_read>surplus_size) {
            this_time_read_len=surplus_size;
            jump_if=False;
        }
        else {
            this_time_read_len=surplus_to_read;
            jump_if=True;
        }
        surplus_size-=this_time_read_len;
        flash_read(&puf[total_read_byte],temp_f->now_addr,this_time_read_len);
        total_read_byte+=this_time_read_len;
        if(jump_if==True) {
            flash_read(next_piece_8,pieceid_to_addr(temp_f->now_piece)+2,2);
            temp_f->now_piece=next_piece_8[0]<<8 | next_piece_8[1];
            temp_f->now_addr=pieceid_to_addr(temp_f->now_piece)+4;
        }
        else {
            ret=True;
        }
    }
    return ret;
}

Bool file_write_data(File_operate_t* temp_f,uint8_t* puf,uint32_t offset_start,uint32_t offset)
{
    Bool ret=False;
    Bool empty_piece_if=False,jump_if=False;
    uint8_t next_piece_8[2],cmd[1],new_size[1],size_get=0,piece_surplus_size=0;
    uint16_t new_piece=0;
    uint32_t surplus_to_write=0,total_write=0;
    uint32_t this_time_write_len=0;
    if(temp_f->init_scusses_if==False) {
        return False;
    }
    if(offset_start>temp_f->now_size) {
        offset_start=temp_f->now_size;
    }
    temp_f->now_offset=0;
    offset_move(temp_f,RIGHT,offset_start);
    surplus_to_write=offset;
    while(surplus_to_write>0) {
        uint32_t this_piece_end_addr=pieceid_to_addr(temp_f->now_piece)+FLASH_USEFUL_DATA_LEN+4;
        uint32_t this_piece_to_write=this_piece_end_addr-temp_f->now_addr;
        if(this_piece_to_write>surplus_to_write) {
            this_time_write_len=surplus_to_write;
            jump_if=False;
        }
        else {
            this_time_write_len=this_piece_to_write;
            jump_if=True;
        }
        surplus_to_write-=this_time_write_len;
        flash_write_page(&puf[total_write],temp_f->now_addr,this_time_write_len);
        total_write+=this_time_write_len;
        size_get=get_piece_size(temp_f->now_piece);
        piece_surplus_size=size_get-(temp_f->now_addr-pieceid_to_addr(temp_f->now_piece)-4);
        if(piece_surplus_size>this_time_write_len) {
            new_size[0]=size_get;
        }
        else {
            new_size[0]=size_get+(this_time_write_len-piece_surplus_size);
        }
        flash_write_page(new_size,pieceid_to_addr(temp_f->now_piece),1);
        if(jump_if==True) {
            flash_read(cmd,pieceid_to_addr(temp_f->now_piece)+1,1);
            if(cmd[0]==JUMP) {
                flash_read(next_piece_8,pieceid_to_addr(temp_f->now_piece)+2,2);
                temp_f->now_piece=next_piece_8[0]<<8 | next_piece_8[1];
                temp_f->now_addr=pieceid_to_addr(temp_f->now_piece)+4;
            }
            else if(cmd[0]==END) {
                for(int i=0;i<FLASH_MAX_SIZE/FLASH_PIECE_MIN_SIZE;i++) {
                    uint8_t flag[1];
                    flash_read(flag,pieceid_to_addr(i),1);
                    if(flag[0]==0xFF) {
                        new_piece=i;
                        empty_piece_if=True;
                        break;
                    }
                }
                if(empty_piece_if==False) {
                    ret=False;
                    break;
                }
                else {
                    uint8_t config_write[3]={JUMP,new_piece<<8,new_piece};
                    flash_write_page(config_write,pieceid_to_addr(temp_f->now_piece)+1,3);
                    temp_f->now_piece=new_piece;
                    flash_write_page(lim32_basic_config.file_init,pieceid_to_addr(temp_f->now_piece),6);
                    flash_write_page(&lim32_basic_config.file_init[6],pieceid_to_addr(temp_f->now_piece+1)-4,4);
                    temp_f->now_addr=pieceid_to_addr(temp_f->now_piece)+4;
                    ret=True;
                }
            }
        }
        else {
            ret=True;
        }
    }
    file_size_calu(temp_f);
    return ret;
}

Bool offset_move(File_operate_t* temp_f,OFFSET_DIRECTION dir,uint32_t distance)
{
    Bool ret=False;
    Bool end_if=False;
    uint32_t distance_surplus;
    uint8_t now_piece_u8[2]={0x00};
    uint8_t cmd[1]={0x00},new_size[4]={0x00};
    uint16_t now_piece=temp_f->start_piece;
    if(temp_f->init_scusses_if==False) {
        return False;
    }
    else {
        file_size_calu(temp_f);
        if(dir==LEFT) {
            if(distance>temp_f->now_offset) {
                temp_f->now_offset=0;
            }
            else {
                temp_f->now_offset-=distance;
            }
        }else if(dir==RIGHT) {
            if(distance+temp_f->now_offset>temp_f->now_size) {
                temp_f->now_offset=temp_f->now_size;
            }
            else {
                temp_f->now_offset+=distance;
            }
        }
        distance_surplus=temp_f->now_offset;
        while(end_if==False) {
            flash_read(now_piece_u8, pieceid_to_addr(now_piece)+2,2);
            if(distance_surplus<=FLASH_USEFUL_DATA_LEN) {
                temp_f->now_piece=now_piece;
                temp_f->now_addr=pieceid_to_addr(temp_f->now_piece)+4+distance_surplus;
                end_if=True;
                ret=True;
            }
            else if(distance_surplus>FLASH_USEFUL_DATA_LEN) {
                now_piece=now_piece_u8[0]<<8 | now_piece_u8[1];
                distance_surplus-=FLASH_USEFUL_DATA_LEN;
            }
            else{
                return False;
            }
        }
    }
    return ret;
}

//void file_in_dir_print()
//{
//    uint32_t file_nums=get_nums();
//    printf("\n\n\n");
//    if(file_nums==0) {
//        printf("no files\n");
//    }
//    else {
//        for(int i=0;i<file_nums;i++) {
//            uint8_t use_full_num=0;
//            uint8_t file_names[12];
//            flash_read(file_names,12+i*20,12);
//            printf("%d:",i);
//            for(int j=0;j<12;j++) {
//                if(file_names[j]!=0) {
//                    printf("%c",file_names[j]);
//                }
//            }
//            printf("\n");
//        }
//    }
//    printf("\n\n\n");
//}



Bool list_compare(uint8_t* l1,uint8_t* l2,uint32_t len)
{
    Bool ret=True;
		for(int i=0;i<12;i++){
			dect_fl[i]=l1[i];
		}
		for(int i=0;i<12;i++){
			dect_fl[i+12]=l2[i];
		}
    for(int i=0;i<len;i++) {
			dect_fl[24]=l1[i];
			dect_fl[25]=l2[i];
        if(l1[i]!=l2[i]) {
            ret=False;
            break;
        }
    }
    return ret;
}

Bool in_dir_if(uint8_t* file,uint32_t file_nums)
{
    if(get_file_id(file,file_nums)==-1) {
        return False;
    }
    else {
        return True;
    }
}

uint32_t get_nums()
{
    uint32_t file_nums=0x00;
    uint8_t nums[4];
    flash_read(nums,4,4);
    file_nums=u8_to_u32(nums);
    return file_nums;
}

int get_file_id(uint8_t* file,uint32_t file_nums)
{
    int file_id_get=-1;
    for(int i=0;i<file_nums;i++) {
        uint8_t f_name[12];
        flash_read(f_name,12+20*i,12);
        if(list_compare(f_name,file,12)==True) {
            file_id_get=i;
            break;
        }
    }
    return file_id_get;
}

uint32_t u8_to_u32(uint8_t* data_u8)
{
    uint32_t ret=0x00;
    for(int i=0;i<4;i++) {
        ret |= (data_u8[i] << (8*(3-i)));
    }
    return ret;
}

void u32_to_u8(uint32_t data_u32,uint8_t* data_u8)
{
    for(int i=0;i<4;i++) {
        data_u8[i]=(data_u32>>(8*(3-i)) & 0xFF);
    }
}

uint32_t pieceid_to_addr(uint16_t id)
{
    return id*FLASH_PIECE_MIN_SIZE+FLASH_CONFIG_LEN;
}

uint8_t get_piece_size(uint16_t id)
{
    uint8_t size_get[1]={0x00};
    flash_read(size_get,pieceid_to_addr(id),1);
    return  size_get[0];
}


#endif
